﻿#include "SDLVideoRenderView.h"
#include <iostream>
using namespace std;
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
}


bool SDLVideoRenderView::IsExit()
{
	return renderUtil->isEventQuit();
}
void SDLVideoRenderView::Close()
{
	//确保线程安全
	unique_lock<mutex> sdl_lock(m_mutex);
	if (nv12_data_cache)
	{
		delete nv12_data_cache;
	}
	renderUtil->Close();
}

bool SDLVideoRenderView::Init(int w, int h, IVideoRenderView::PixFormat fmt, void* win_id)
{
	renderUtil = SDLRenderUtil::Create();
	if (w <= 0 || h <= 0)return false;
	//确保线程安全
	unique_lock<mutex> sdl_lock(m_mutex);
	//初始化SDL 视频库
	renderUtil->width = w;
	renderUtil->height = h;
	renderUtil->winId = win_id;
	renderUtil->PIX_FMT = fmt;//渲染模式，这个地方等下需要改
	return renderUtil->Init();
}

bool SDLVideoRenderView::Draw(char* data)
{
	if (!data)return false;
	renderUtil->isEventQuit();
	unique_lock<mutex> sdl_lock(m_mutex);
	if (m_scale_width > 0 && m_scale_height > 0) {
		renderUtil->width = m_scale_width;
		renderUtil->height = m_scale_height;
	}
	return renderUtil->Render(data);
}

bool SDLVideoRenderView::DrawFrame(AVFrame* frame)
{
	if (!frame || !frame->data[0])return false;
	unique_lock<mutex> sdl_lock(m_mutex);
	m_count++;
	if (m_beg_ms <= 0)
	{
		m_beg_ms = clock();
	}
	//计算显示帧率
	else if ((clock() - m_beg_ms) / (CLOCKS_PER_SEC / 1000) >= 1000) //一秒计算一次fps
	{
		m_render_fps = m_count;
		m_count = 0;
		m_beg_ms = clock();
	}

	switch (frame->format)
	{
	case AV_PIX_FMT_YUV420P:
		return renderUtil->DrawFrame(frame->data[0], frame->data[1], frame->data[2], frame->linesize[0], frame->linesize[1], frame->linesize[2]);
	case AV_PIX_FMT_NV12:
	{
		if (!nv12_data_cache)
		{
			nv12_data_cache = new char[frame->width * frame->height * 1.5];
		}
		//将data的数据复制到缓存中
		if (frame->linesize[0] == frame->width)//字节对齐了
		{
			memcpy(nv12_data_cache, frame->data[0], frame->linesize[0] * frame->height);//y
			memcpy(nv12_data_cache + frame->linesize[0] * frame->height, frame->data[1], frame->linesize[1] * frame->height / 2);//uv
		}
		else {//字节未对齐需要逐行复制
			//先复制y
			for (int i = 0;i < frame->height;i++)
			{
				memcpy(nv12_data_cache + i * frame->linesize[0], frame->data[0] + frame->linesize[0] * i, frame->width);
			}

			//再复制uv
			for (int i = 0;i < frame->height / 2;i++)
			{
				auto p = nv12_data_cache + frame->height * frame->width;
				memcpy(p + i * frame->width, frame->data[1] + i * frame->linesize[1], frame->width);
			}
		}
		int data_size = frame->width * frame->height * 1.5;
		return renderUtil->DrawFrame((const unsigned char*)nv12_data_cache, data_size);
	}
	case AV_PIX_FMT_BGRA:
	case AV_PIX_FMT_ARGB:
	case AV_PIX_FMT_RGBA:
	case AV_PIX_FMT_RGB24:
		return renderUtil->DrawFrame(frame->data[0], frame->linesize[0]);
	}
	return true;
}

